package com.dk.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.LinkedHashMap;
import java.util.Map;
@Configuration //成为配置类
public class ShrioConfig {

    @Bean //实列化到spring容器中
    public ShiroFilterFactoryBean getShiroFilterFactoryBean(@Autowired DefaultWebSecurityManager securityManager){
        //创建ShiroFilterFactoryBean对象,shrio 的过滤器(工厂)
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
        //配置shiro的内置过滤器
        Map<String,String> filterMap = new LinkedHashMap<>(); //LinkedHashMap()存储有序
        filterMap.put("/img/**","anon");
        filterMap.put("/js/**","anon");
        filterMap.put("/assets/**","anon");
        filterMap.put("/logenController/listGet","anon");
        filterMap.put("/textController/list","perms[text:man]");
        filterMap.put("/xx","perms[add:add]");
        filterMap.put("/tRoleController/list","perms[role:man]");
        filterMap.put("/menuController/listGet","perms[menu:man]");
        filterMap.put("/auth/logout","logout");//自动配置退出功能(自带提供)
        filterMap.put("/**","authc"); // /**拦截多层路径 如:/userController/list

        /*
        * anon : 不需要登录就能访问的路径
        * authc : 必须登录才能访问
        * perms : 登录后也不行,还得和我们设置的权限一样才能访问(该路径必须有权限才能访问)
        * */

        //自定义登录页面
        shiroFilterFactoryBean.setLoginUrl("/logenController/toLogin"); //意思是拦截所有路径后指定他到一个路径
        shiroFilterFactoryBean.setUnauthorizedUrl("/logenController/unauthorized"); //无权访问的页面
        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;
    }

    //创建DefaultWebSecurityManager 用来管理用户主体的Subject
    @Bean //实列化到spring容器中
    public DefaultWebSecurityManager getDefaultWebSecurityManager(@Autowired UserRealm userRealm){
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        //关联自定义的realm
        securityManager.setRealm(userRealm);
        return securityManager;
    }

    //实例化自定义的Realm类
    @Bean
    public UserRealm getUserRealm(@Autowired HashedCredentialsMatcher hashedCredentialsMatcher){
        UserRealm userRealm = new UserRealm();
        //设置加密
        userRealm.setCredentialsMatcher(hashedCredentialsMatcher);
        return userRealm;
    }

    @Bean
    //设置加密组件
    public HashedCredentialsMatcher getHashedCredentialsMatcher(){
        HashedCredentialsMatcher hashedCredentialsMatcher = new HashedCredentialsMatcher();
        //1.指定加密方式
        hashedCredentialsMatcher.setHashAlgorithmName("MD5"); //MD5 SHA-1 SHA-256
        //2.指定加密次数
        hashedCredentialsMatcher.setHashIterations(10); //加密次数
        //3.开启Hex编码方式
        hashedCredentialsMatcher.setStoredCredentialsHexEncoded(true);
        return hashedCredentialsMatcher;
    }

    @Bean
    public ShiroDialect getShiroDialect(){
        return new ShiroDialect();
    }
}
